  /**
 * @file    sample.c
 * @brief   服务层-采样模块
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-04-26
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-26 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "sample.h"
#include "cfg_prj.h"
#include "filter.h"
#include "base_math.h"
#include "dev_afe.h"
#include "param_mng.h"
#include "var_mng.h"
#include "drv_adc.h"
#include "ntc_3950_res.h"
#include "diagnosis.h"
#include "event_mng.h"
#include "If_do.h"
#include "FreeRTOS.h"
#include "task.h"
#include "diag_sys.h"
#include "If_di.h"
#include "drv_gpio_pcfg.h"
#include "drv_gpio.h"
#include "ka495xx_driver.h"
/* macro/define --------------------------------------------------------------*/
#define FILTER_CVOLT_DEEP        (50)
#define FILTER_CV_JUMP           (200)

#define FILTER_CURR_DEEP         (20)   // 滤波深度
#define FILTER_CURR_JUMP         (2000) // 0.1A 电流跳变值 

#define FILTER_TEMP_DEEP         (40)
#define FILTER_TEMP_JUMP         (100)
#define FILTER_PACKV_DEEP        (10)
#define FILTER_PACKV_JUMP        (50)

#define ERR_TRY_TIMES            (5)
#define ERR_INIT_TIMES           (50)

#define TEMP_FILTER_NUM          (CFG_TEMP_NUM + 3)

#define CURR_DR_DLY              (1000)

#define LIMIT_STATE_ON           (1)
#define LIMIT_STATE_OFF          (0)

#define LIMIT_OPEN_INIT          (0)
#define LIMIT_OPEN_RUNNING       (1)

#define LIMIT_OPEN_DELAY         (500)
#define LIMIT_NO_CURR_MAX        (2)       /* 限流电流小于多少判定为无电流 */
#define LIMIT_NO_CURR_OFF_DLY    (180000)  /* 持续多久电流小于某个值则关闭限流 mS */

#define LIMIT_TRY_TIME           (1800000) /* 半个小时尝试一次 */

#define CURR_SMP_POINTS          (800) // 采样点1000个

#define PRECHG_TIME              (500)
#define FAULT_CLEAR_TIMES       (14400000) //4H
/* typedef -------------------------------------------------------------------*/
/**
 * @brief 缓冲数据
 */
typedef struct 
{
    float src_curr ; 
    uint16_t src_pack_volt ;

    float batt_volt;
    float bus_curr;
    uint16_t pack_volt;
    uint16_t sum_volt;
    uint16_t cv_src_buf[CELL_MAX_NUM];
    uint16_t cell_volt_buf[CELL_MAX_NUM];
    uint16_t ct_src_buf[CFG_TEMP_NUM];
    uint16_t cell_temp_buf[CFG_TEMP_NUM];
    float mos_temp;
    float env_temp;

    uint16_t agv_temp;
    uint16_t age_volt;
    uint64_t cell_ol_state;
    uint16_t temp_ol_state;
    uint16_t volt_diff;
    uint16_t temp_diff;
    idx_data_type min_volt_obj;
    idx_data_type max_volt_obj;
    idx_data_type min_temp_obj;
    idx_data_type max_temp_obj;

    uint16_t blc_chl;

    uint8_t afe_status;
    uint16_t afe_comm_err;
}smp_data_type;

/* local functions -----------------------------------------------------------*/
static int16_t find_ntc_table(uint32_t res , ntc_table_type ntc_data);
static uint8_t is_happen_chg_prp(void);
static uint8_t is_happen_dsg_prp(void);
static uint8_t smp_blc_is_open(void);
static uint8_t is_happen_limit_prp(void);
static uint8_t is_open_limit(void);
/* static variables ----------------------------------------------------------*/
static filter_type cvolt_filter_buf[CELL_MAX_NUM];   /* 滤波缓冲区 */
static uint16_t cvolt_filter_data_buf[CELL_MAX_NUM][FILTER_CVOLT_DEEP] = {0};

static filter_type curr_filter_obj = {0};
static uint16_t curr_filter_data_buf[FILTER_CURR_DEEP] = {0};
static filter_type temp_filter_buf[TEMP_FILTER_NUM] = {0};
static uint16_t temp_filter_data_buf[TEMP_FILTER_NUM][FILTER_TEMP_DEEP] = {0};

static smp_data_type smp_data_obj = {0};
static uint8_t prechg_flag = 1;
static uint8_t cmd_clr_sc = 0;
static uint16_t prechg_dly = 0;
static uint16_t chg_curr_cnt = 0;
static uint16_t dsg_curr_cnt = 0;
static uint16_t idle_curr_cnt = 0;
static uint32_t fault_clear_cnt = 0;
static uint8_t open_prechg = 0;
/* 限流类参数 */
static uint8_t limit_state = 0;
static uint8_t limit_step = LIMIT_OPEN_INIT;
static uint32_t limit_open_delay = 0;
static float bus_curr = 0;
uint8_t afe_deinit_flag = 0;
static uint8_t first_pwr = 0;

//static uint32_t limit_no_curr_delay = 0;
extern volatile uint32_t g_u32PCIntFlag;

/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief 采样初始化 
 */
void sample_init(void)
{
    uint8_t i = 0;
    
    drv_adc_init();

    dev_afe_init(param_get_data(PAR_ID_CB_CELL_NUM));
                 
    for( i = 0;i < CELL_MAX_NUM; ++ i)
    {
        filter_login(&cvolt_filter_buf[i] , cvolt_filter_data_buf[i] ,FILTER_CVOLT_DEEP , FILTER_CV_JUMP);
    }

    for( i = 0;i < TEMP_FILTER_NUM ; ++ i)
    {
        filter_login(&temp_filter_buf[i] , temp_filter_data_buf[i] ,FILTER_TEMP_DEEP , FILTER_TEMP_JUMP);
    }
	
    filter_login(&curr_filter_obj , curr_filter_data_buf , FILTER_CURR_DEEP , FILTER_CURR_JUMP);
	
	sample_hard_ver();
}

/**
 * @brief 前端采样模块处理 (运行周期 100mS)
 */
void sample_afe_deal(uint16_t cycle)
{
    uint8_t try_cnt = 0;
	afe_alm_type alarm_msg = {0};
	uint8_t cmos = 0,dmos = 0;
	uint8_t i = 0;
	uint16_t mos_ctrl = 0;
	uint16_t cell_ol_state = 0;
	float now_curr = 0;
	
    do
    {
	/*新增20241029*/
		if(afe_deinit_flag)
		{
			afe_deinit_flag = 0;
			dev_afe_init(param_get_data(PAR_ID_CB_CELL_NUM));
		}
		
        smp_data_obj.afe_status = dev_ka495xx_is_active();
        if(TRUE == smp_data_obj.afe_status)
            break;
    } while (try_cnt ++ < ERR_TRY_TIMES);
    
    if(TRUE == smp_data_obj.afe_status)
    {
        smp_data_obj.afe_comm_err = 0; 
		diag_set_prp(PRP_ID_FT_AFE , 0);		
    }
    else
    {
		++ smp_data_obj.afe_comm_err ;
        /** AFE 掉线故障 */
        if(smp_data_obj.afe_comm_err == ERR_INIT_TIMES)
        {
            /* 数据缓冲区清零 */
            dev_afe_init(param_get_data(PAR_ID_CB_CELL_NUM));
        }
		if(smp_data_obj.afe_comm_err >= ERR_INIT_TIMES + 5)
		{
			for(i = 0;i < CELL_MAX_NUM; ++ i)
			{
				smp_data_obj.cell_volt_buf[i] = 100;
				var_set_data(VAR_ID_CELL_VOLT01 + i , 100);
				cell_ol_state |= (1 << i);
			}
			var_set_data(VAR_ID_MAX_CELL_VOLT,CELL_ERR_VOLT);
			var_set_data(VAR_ID_MIN_CELL_VOLT,CELL_ERR_VOLT);			
			if(diag_get_prp(PRP_ID_FT_AFE) == 0)
				event_add_to_sram(EVT_ID_FT_AFE , smp_data_obj.afe_comm_err , ERR_INIT_TIMES);
			diag_set_prp(PRP_ID_FT_AFE , 1);
			smp_data_obj.cell_ol_state = cell_ol_state;
			var_set_data(VAR_ID_CELL_OL_ST , cell_ol_state);
            dev_afe_init(param_get_data(PAR_ID_CB_CELL_NUM));
            smp_data_obj.afe_comm_err = 0;
        }
    }
	// 判断反接保护 
  //  if ((g_u32PCIntFlag == 1) &&(drv_gpio_read_pin(RESEVER_PORT , RESEVER_PIN) == 0))
    if ((drv_gpio_read_pin(RESEVER_PORT , RESEVER_PIN) == 0))		
    {
		diag_set_prp(PRP_ID_FT_REVERSE , TRUE);
	//	If_do_set_output(DO_DMOS_CTRL , DO_OUT_OFF);
    //  If_do_set_output(DO_CMOS_CTRL , DO_OUT_OFF);
		prechg_flag = 0; // 关闭预充
		//g_u32PCIntFlag = 0;
    }	
	else
	{
	//	If_do_set_output(DO_DMOS_CTRL , DO_OUT_ON);
	//	If_do_set_output(DO_CMOS_CTRL , DO_OUT_ON);
		diag_set_prp(PRP_ID_FT_REVERSE , FALSE);
	}

	if(TOOL_MODE_DEBUG != var_get_data(VAR_ID_TOOL_MODE))
    {
        if(1 == prechg_flag)
        {
            /* 开启预充*/
            if(prechg_dly == 0)
            {
				dev_afe_clr_sc_alarm();
				dev_afe_ctrl_mos(1 , 0);
				If_do_set_output(DO_DMOS_CTRL , DO_OUT_OFF);
                If_do_set_output(DO_PCHG_CTRL , DO_OUT_ON);
                prechg_dly += cycle;
            }
            else
            {
                /* 预充延时 */
				if(diag_get_prp(PRP_ID_FT_REVERSE) == FALSE)
				{
					prechg_dly += cycle;
					if(prechg_dly >= PRECHG_TIME)
					{
						dmos = 1;
						dev_afe_ctrl_mos(1 , dmos);
						vTaskDelay(5);
						If_do_set_output(DO_DMOS_CTRL , DO_OUT_ON);
						vTaskDelay(5);
						If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
						prechg_flag = 0;
						prechg_dly = 0;
					}
					else
					{
						If_do_set_output(DO_LIMIT_10A ,DO_OUT_OFF);
					}					
				}
				else
				{
					prechg_flag = 0;
					prechg_dly = 0;
					If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
				}
            }
       }
       else
       {
			if(LIMIT_STATE_ON != limit_state)
			{
				if((TRUE == is_happen_chg_prp()) || (((var_get_data(VAR_ID_MOS_LOCK) & 0xAA01) == 0xAA01) && (var_get_data(VAR_ID_CURR_DR) != CURR_DR_DSG)))
				{
					cmos = 0;
					if(TRUE == is_open_limit())
					{
						limit_open_delay = 0;
						limit_step = LIMIT_OPEN_INIT;
						limit_state = LIMIT_STATE_ON;
						}
						else
						{
							If_do_set_output(DO_LIMIT_10A ,DO_OUT_OFF);
						}
					}
					else
					{
						cmos = 1;
						If_do_set_output(DO_LIMIT_10A ,DO_OUT_OFF);
					}
				}
				else
				{
					switch(limit_step)
					{
						case LIMIT_OPEN_INIT:
							limit_open_delay += cycle;
                            cmos = 0;
							if(limit_open_delay >= LIMIT_OPEN_DELAY)
							{
								limit_step = LIMIT_OPEN_RUNNING;
								limit_open_delay = 0;
								If_do_set_output(DO_LIMIT_10A ,DO_OUT_ON);
							}
							break;
						case LIMIT_OPEN_RUNNING:
							now_curr = var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
							/* 有放电电流或者有非充电过流保护充电类保护 ,关闭限流*/
							if((TRUE == is_happen_limit_prp()) || (var_get_data(VAR_ID_CURR_DR) == CURR_DR_DSG))
							{
								limit_state = LIMIT_STATE_OFF;
							}
							else
							{
								//TODO 如果持续
//								curr_val = var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
//								if((curr_val >= 0) && ( curr_val < 2))
//								{
//									limit_no_curr_delay += cycle;
//									if(limit_no_curr_delay >= LIMIT_NO_CURR_OFF_DLY)
//									{
//										limit_no_curr_delay = 0;
//										limit_state = LIMIT_STATE_OFF;
//									}
//								}
//								else
//								{
//									limit_no_curr_delay = 0;
//								} 
								// 限流持续时间超过多久后，主动尝试开启一次 
							}
							break;
						default:
							break;
					}
					
					if(LIMIT_STATE_OFF == limit_state)
					{
						dev_afe_ctrl_mos(1 ,1);	
						vTaskDelay(10);
						If_do_set_output(DO_LIMIT_10A ,DO_OUT_OFF);
						vTaskDelay(10);
					}
				}
			
                if((TRUE == is_happen_dsg_prp()) || ((var_get_data(VAR_ID_MOS_LOCK) & 0xAA02) == 0xAA02))
                {
                    dmos = 0;
					open_prechg = 0;
					prechg_dly = 0;
                    If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
                }
                else
				{
					// 如果放电MOS是闭合状态，不处理
					if(var_get_data(VAR_ID_MOS_STATE) & (1 << VAR_MOS_ST_DSG))
					{
						dmos = 1;
						open_prechg = 0;
						If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
					}
					else
					{
						// 充电状态 直接闭合
						if(CURR_DR_CHG == var_get_data(VAR_ID_CURR_DR))
						{
							dmos = 1;
							open_prechg = 0;
							If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
						}
						else
						{
							if(0 == open_prechg)
							{
								prechg_dly = 0;
								open_prechg = 1;
							}
							dmos = 0;
									
							if(1 == open_prechg)
							{
								if(0 == prechg_dly)
								{
									dmos = 0;
									If_do_set_output(DO_PCHG_CTRL , DO_OUT_ON);
									prechg_dly += cycle;
								}
								else
								{
									/* 预充延时 */
									prechg_dly += cycle;
									if(prechg_dly >= PRECHG_TIME)
									{
										dmos = 1;
										dev_afe_ctrl_mos(cmos , dmos);
										vTaskDelay(5);
										If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
										prechg_dly = 0;
										open_prechg = 0;
									}
									else
									{
										dmos = 0;
									}
								}
							}
							else
							{
								dmos = 1;
							}
						}
					}
				}
	
				dev_afe_ctrl_mos(cmos , dmos);
            }
        }
        else
        {
            mos_ctrl = var_get_data(VAR_ID_MOS_CTRL);
           // cmos = mos_ctrl & 0x01;
			
			if(((mos_ctrl >> 0) & 0x01)&&(var_get_data(VAR_ID_MAX_CELL_VOLT) < param_get_data(PAR_ID_COV_PRP_VAL) + 10))
			    cmos = 1;
          //  dmos = (mos_ctrl >> 1) & 0x01;
			 
			if(((mos_ctrl >> 1) & 0x01)&&(var_get_data(VAR_ID_MIN_CELL_VOLT) > param_get_data(PAR_ID_CUV_PRP_VAL) - 10))
				  
                dmos = 1;
            if((mos_ctrl >> 2) & 0x01)
               If_do_set_output(DO_PCHG_CTRL , DO_OUT_ON);
            else
               If_do_set_output(DO_PCHG_CTRL , DO_OUT_OFF);
                
            if(mos_ctrl & (1 << 3))
			{ 
			  If_do_set_output(DO_HOT_CTRL , DO_OUT_ON);
			  If_do_set_output(DO_LIMIT_5A , DO_OUT_ON);
			}
            else
			{
              If_do_set_output(DO_HOT_CTRL , DO_OUT_OFF);
			  If_do_set_output(DO_LIMIT_5A , DO_OUT_OFF);   //增加限流5A和加热一起控制
			}   
            if(mos_ctrl & (1 << 5))
               If_do_set_output(DO_LIMIT_10A , DO_OUT_ON);
            else
               If_do_set_output(DO_LIMIT_10A , DO_OUT_OFF);
            
            if(mos_ctrl & (1 << 6))
               If_do_set_output(DO_CAN_RES , DO_OUT_ON);
            else
               If_do_set_output(DO_CAN_RES , DO_OUT_OFF);
            
            dev_afe_ctrl_mos(cmos , dmos);
        }
            
        /* 清除故障状态 - 无短路保护故障直接清除 */
		dev_afe_read_alarm(&alarm_msg);
		var_set_data(VAR_ID_SRC_AFE_ALM , alarm_msg.alarm);
		if((alarm_msg.alarm) && (alarm_msg.bit.sc == 0))
		{
			dev_afe_clr_alarm();
		}
		else
		{
			if(cmd_clr_sc)
			{
				if(TRUE == dev_afe_clr_sc_alarm())
				{
					cmd_clr_sc = 0;
				}
			}
		}
        /* mos状态更新 */
		dev_afe_get_mos_state(&cmos , &dmos);
		var_set_data(VAR_ID_MOS_STATE ,(dmos << VAR_MOS_ST_DSG) | ( cmos << VAR_MOS_ST_CHG));
}

/**
 * @brief  计算采集电流值
 * @param  curr
 */
extern ka495xx_smp_type ka495xx_smp_data;
void sample_curr(uint16_t cycle)
{
    int32_t var_temp = 0;
    int32_t filter_curr = 0;
    float k = 0;
	uint8_t cmos = 0;
	uint8_t dmos = 0;
	uint16_t set_val = 0;
//    float b = 0; 
    float curr_zero = 0;
    double calc_curr = 0;
    double curr_volt = 0;
	
	if(FALSE == smp_data_obj.afe_status)
	{
		return;
	}
	
	dev_ka495xx_read_curr();
    calc_curr = (double)ka495xx_smp_data.smp_bus_curr * 0.001;
	
	// 第一次上电 零点自动补偿
	if(first_pwr == 0)
	{
		dev_afe_get_mos_state(&cmos , &dmos);
		if((cmos == 0) && (dmos == 0))
		{
			if(PARAM_ZERO_VAILD(calc_curr))
			{
				set_val = (smp_data_obj.src_curr + VAR_CURR_OFFSET)/VAR_CURR_FACTOR;
				param_set_data(PAR_ID_CB_ZERO_SET , set_val);
			}
		}
		first_pwr = 1;
	}
    var_temp = (calc_curr + VAR_CURR_OFFSET)/VAR_CURR_FACTOR;
    filter_curr = filter_calc(&curr_filter_obj , var_temp);
	calc_curr = filter_curr * VAR_CURR_FACTOR - VAR_CURR_OFFSET;

	smp_data_obj.src_curr = calc_curr;
    var_temp = (smp_data_obj.src_curr + VAR_CURR_OFFSET)/VAR_CURR_FACTOR;
    var_set_data(VAR_ID_SRC_CURR , var_temp);
    /* 电流零点校准 */
    curr_zero = param_get_data(PAR_ID_CB_ZERO_SET);
	curr_zero = curr_zero* VAR_CURR_FACTOR - VAR_CURR_OFFSET;
    if(PARAM_ZERO_VAILD(curr_zero))
    {
        calc_curr -= curr_zero;
    }
    /** 充电为正，放电为负 */
    if(calc_curr >= 0)
    {
        k = param_get_data(PAR_ID_CB_CC_K);
    }
    else
    {
        k = param_get_data(PAR_ID_CB_DC_K);
    }

    if(PARAM_K_IS_VAILD(k))
    {
        calc_curr = calc_curr * k * PARAM_K_FCATOR;
    }
	/* 赋值到缓冲区 */
    if((calc_curr > -ZERO_DRIFT) && (calc_curr < ZERO_DRIFT))
	{
		calc_curr = 0;
	}
	bus_curr = calc_curr;
	var_temp = (calc_curr + VAR_CURR_OFFSET)/VAR_CURR_FACTOR;
    var_set_data(VAR_ID_BUS_CURR , var_temp);
    /* 判断电流方向 */
    if(calc_curr > ZERO_DRIFT)
	{
		chg_curr_cnt += cycle;
		if(chg_curr_cnt >= CURR_DR_DLY)
		{
			dsg_curr_cnt = 0; 
			idle_curr_cnt = 0;
			if(var_get_data(VAR_ID_CURR_DR) != CURR_DR_CHG)
			{	
				var_set_data(VAR_ID_CURR_DR , CURR_DR_CHG);
				event_add_to_sram(EVT_ID_IN_CHG , var_get_data(VAR_ID_BUS_CURR), (ZERO_DRIFT + VAR_CURR_OFFSET)/VAR_CURR_FACTOR);				
			}
		}
	}
	else if(calc_curr <= -ZERO_DRIFT)
	{	
		dsg_curr_cnt += cycle;
		if(dsg_curr_cnt >= CURR_DR_DLY)
		{
			chg_curr_cnt = 0;
			idle_curr_cnt = 0;
			if(var_get_data(VAR_ID_CURR_DR) != CURR_DR_DSG)
			{	
				var_set_data(VAR_ID_CURR_DR , CURR_DR_DSG);
				event_add_to_sram(EVT_ID_IN_DSG,var_get_data(VAR_ID_BUS_CURR), (-ZERO_DRIFT + VAR_CURR_OFFSET)/VAR_CURR_FACTOR);				
			}
		}
	}
	else
	{
		idle_curr_cnt += cycle;
		if(idle_curr_cnt >= CURR_DR_DLY)
		{
			chg_curr_cnt = 0;
			dsg_curr_cnt = 0;
			var_set_data(VAR_ID_CURR_DR , CURR_DR_IDLE);
		}
	}
}  

/**
 * @brief 采集电压
 */
void sample_volt(void)
{
    uint16_t cell_volt_buf[CELL_MAX_NUM] = {0};
    uint16_t k = 0;
	uint16_t i = 0;
	uint16_t temp = 0;
	uint32_t sum_volt = 0;
	uint8_t cell_num = 0; 
	uint64_t cell_ol_state = 0;

	//读取总电压 
    smp_data_obj.batt_volt = drv_adc_read_chal(EADC_CHNL_BATTV);
    //
//    if(FALSE == smp_data_obj.afe_status)
//        return ;
    
	cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
	
	dev_ka495xx_read_cv_blc(cell_num , cell_volt_buf , smp_data_obj.cell_temp_buf);
 
    smp_data_obj.min_volt_obj.idx = 1;
    smp_data_obj.min_volt_obj.data = 0xffff;
    smp_data_obj.max_volt_obj.idx = 1;
    smp_data_obj.max_volt_obj.data = 0;
    for( i = 0;(i < CELL_MAX_NUM) && (i < cell_num); ++ i)
    {
        temp = filter_calc(&cvolt_filter_buf[i] , cell_volt_buf[i]);	
	//	temp = cell_volt_buf[i];
        smp_data_obj.cv_src_buf[i] = cell_volt_buf[i];				
        k = param_get_data(PAR_ID_CB_CV01_K + i);
        if(PARAM_K_IS_VAILD(k))
        {
            smp_data_obj.cell_volt_buf[i] = temp * k * PARAM_K_FCATOR;
        }
        else
        {
            smp_data_obj.cell_volt_buf[i] = temp;
        }

        if((smp_data_obj.cell_volt_buf[i] < CELL_VOLT_MIN)
            ||(CELL_VOLT_MAX < smp_data_obj.cell_volt_buf[i]))
        {
            cell_ol_state |= (1 << i);
            smp_data_obj.cell_volt_buf[i] = 100;
        }

        var_set_data(VAR_ID_CELL_VOLT01 + i , smp_data_obj.cell_volt_buf[i]);

        if(smp_data_obj.min_volt_obj.data > smp_data_obj.cell_volt_buf[i])
        {
            smp_data_obj.min_volt_obj.data = smp_data_obj.cell_volt_buf[i];
            smp_data_obj.min_volt_obj.idx = i + 1;
        }

        if(smp_data_obj.max_volt_obj.data < smp_data_obj.cell_volt_buf[i])
        {
            smp_data_obj.max_volt_obj.data = smp_data_obj.cell_volt_buf[i];
            smp_data_obj.max_volt_obj.idx = i + 1;
        }
		
		sum_volt += smp_data_obj.cell_volt_buf[i];
    }
	
	if(cell_num != 0)
		smp_data_obj.age_volt = sum_volt / cell_num;
	var_set_data(VAR_ID_AGV_VOLT , smp_data_obj.age_volt);
	smp_data_obj.sum_volt = sum_volt * 0.1;
    var_set_data(VAR_ID_MAX_CELL_SN, smp_data_obj.max_volt_obj.idx);
    var_set_data(VAR_ID_MAX_CELL_VOLT, smp_data_obj.max_volt_obj.data);
    var_set_data(VAR_ID_MIN_CELL_SN, smp_data_obj.min_volt_obj.idx);
    var_set_data(VAR_ID_MIN_CELL_VOLT, smp_data_obj.min_volt_obj.data);
    smp_data_obj.cell_ol_state = cell_ol_state;
    var_set_data(VAR_ID_CELL_OL_ST, cell_ol_state);
    smp_data_obj.volt_diff = smp_data_obj.max_volt_obj.data - smp_data_obj.min_volt_obj.data;
    var_set_data(VAR_ID_VOLT_DIFF, smp_data_obj.volt_diff);
	var_set_data(VAR_ID_BATT_VOLT, smp_data_obj.sum_volt);
}

void sample_temp(void)
{
	uint8_t i = 0;
    uint32_t sum = 0;
    uint16_t temp_ol = 0;
	uint32_t temp_val = 0;
	int32_t calc_val = 0;
	uint8_t ol_temp_num = 0;
	uint8_t temp_num = 0;
	
	smp_data_obj.min_temp_obj.idx = 1;
    smp_data_obj.min_temp_obj.data = 0xffff;
    smp_data_obj.max_temp_obj.idx = 1;
    smp_data_obj.max_temp_obj.data = 0;
	
	temp_num = param_get_data(PAR_ID_CB_TEMP_NUM);	
	
    for( i = 0;i < temp_num; ++ i)
    {
        temp_val = smp_data_obj.cell_temp_buf[i];
        calc_val = find_ntc_table(temp_val , ntc_sns103F_3950_data) + 500;
		smp_data_obj.cell_temp_buf[i] = filter_deep_calc(&temp_filter_buf[i],calc_val);
		var_set_data(VAR_ID_CELL_TEMP01 + i , calc_val);
        if(INVALID_TEMP == calc_val)
        {
            temp_ol |= (1 << i);
        }
		else
		{
			++ ol_temp_num;
			if(smp_data_obj.min_temp_obj.data > smp_data_obj.cell_temp_buf[i])
	        {
	            smp_data_obj.min_temp_obj.data = smp_data_obj.cell_temp_buf[i];
	            smp_data_obj.min_temp_obj.idx = i + 1;
	        }

	        if(smp_data_obj.max_temp_obj.data < smp_data_obj.cell_temp_buf[i])
	        {
	            smp_data_obj.max_temp_obj.data = smp_data_obj.cell_temp_buf[i];
	            smp_data_obj.max_temp_obj.idx = i + 1;
	        }
			sum += smp_data_obj.cell_temp_buf[i];
		}
    }
	
	if(ol_temp_num == 0)
	{
		smp_data_obj.agv_temp = INVALID_TEMP + 500;
		smp_data_obj.min_temp_obj.data  = INVALID_TEMP + 500;
		smp_data_obj.max_temp_obj.data = INVALID_TEMP + 500;
	}
	else
		smp_data_obj.agv_temp = sum / ol_temp_num;
	
    var_set_data(VAR_ID_AGV_TEMP , smp_data_obj.agv_temp);
	var_set_data(VAR_ID_MIN_TEMP_SN , smp_data_obj.min_temp_obj.idx);
	var_set_data(VAR_ID_MIN_TEMP_VAL, smp_data_obj.min_temp_obj.data);
	var_set_data(VAR_ID_MAX_TEMP_SN , smp_data_obj.max_temp_obj.idx);
	var_set_data(VAR_ID_MAX_TEMP_VAL , smp_data_obj.max_temp_obj.data);
	
	temp_val = drv_adc_read_reg(EADC_CHNL_AMB);
	temp_val = NTC_PULL_UP_RES * temp_val / (ADC_VREF_REG - temp_val);
	calc_val = find_ntc_table(temp_val , ntc_sns103B_3950_data);
	smp_data_obj.env_temp = filter_deep_calc(&temp_filter_buf[CFG_TEMP_NUM] , calc_val + 500) ;
	var_set_data(VAR_ID_ENV_TEMP , smp_data_obj.env_temp );
    if(INVALID_TEMP == calc_val)
    {
        temp_ol |= (1 << 14);
    }
	
	temp_val = drv_adc_read_reg(EADC_CHNL_MOS);
	temp_val = NTC_PULL_UP_RES * temp_val / (ADC_VREF_REG - temp_val);
    calc_val = find_ntc_table(temp_val , ntc_sns103F_3950_data);
	smp_data_obj.mos_temp = filter_deep_calc(&temp_filter_buf[CFG_TEMP_NUM + 1] , calc_val + 500) ;
	var_set_data(VAR_ID_MOS_TEMP , smp_data_obj.mos_temp );
    if(INVALID_TEMP == calc_val)
    {
        temp_ol |= (1 << 15);
    }
	smp_data_obj.temp_ol_state = temp_ol;
	var_set_data(VAR_ID_TEMP_OL_ST , temp_ol);
	/* 重新启动采样 */
	drv_adc_start();
}

void sample_balance_ctrl(void)
{
    uint16_t blc_chal = 0;
	uint8_t i = 0;
    uint16_t blc_open_volt = param_get_data(PAR_ID_BLC_VOLT);
    uint16_t blc_open_vdiff = param_get_data(PAR_ID_BLC_VDIFF);
    static uint8_t parity = 0;
	uint8_t cell_num = 0;
	
	cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
	if(cell_num >= CELL_MAX_NUM)
		cell_num = CELL_MAX_NUM;
	
    if(TRUE == smp_data_obj.afe_status)
    {
        /* 工装模式 */
        if(var_get_data(VAR_ID_TOOL_MODE) == TOOL_MODE_DEBUG)
        {
            dev_afe_ctrl_balance(var_get_data(VAR_ID_CTRL_BLC) ,  param_get_data(PAR_ID_CB_CELL_NUM));
            var_set_data(VAR_ID_BLC_NOW_IDX , var_get_data(VAR_ID_CTRL_BLC));
        }
        else
        {
            if((smp_data_obj.max_volt_obj.data > blc_open_volt)
                && (smp_data_obj.volt_diff >= blc_open_vdiff) && (TRUE == smp_blc_is_open()))
            {
                for( i = 0;i < cell_num; ++ i)
                {
                    if((smp_data_obj.cell_volt_buf[i] > blc_open_volt)
                        &&(smp_data_obj.cell_volt_buf[i] - smp_data_obj.min_volt_obj.data > (blc_open_vdiff / 2)))
                    {
                        blc_chal |= (1 << i);
                    }
                }
                var_set_data(VAR_ID_BLC_NOW_IDX , blc_chal);
                if(((blc_chal & 0x5555) == 0) || ((blc_chal & 0xAAAA) == 0))
                {
                    dev_afe_ctrl_balance(blc_chal , cell_num);
                    parity = 0;
                }
                else
                {
                    if(parity < 20)
                    {
                        dev_afe_ctrl_balance(blc_chal & 0x5555 , cell_num);
                    }
                    else if(parity < 40)
                    {
                        dev_afe_ctrl_balance(blc_chal & 0xAAAA , cell_num);   
                    }
                    else
                    {
                        parity = 0;
                    }

                    parity ++ ;
                }
            }
            else
            {
                dev_afe_ctrl_balance(0 , cell_num);
				var_set_data(VAR_ID_BLC_NOW_IDX , 0);
            }
        }
        return ;
    }
    else
    {
      //  dev_afe_ctrl_balance(0 , cell_num);
		var_set_data(VAR_ID_BLC_NOW_IDX , 0);
    }
}

void sample_hard_ver(void)
{
	uint16_t smp_volt = 0;
	uint8_t calc_ver = 0;
	
	smp_volt = drv_adc_read_chal(EADC_CHAL_HVER);
	
    if (smp_volt >= 2500) 
	{
        calc_ver = 9;
    } 
	else if (smp_volt >= 1500) 
	{
        calc_ver = 5;
    } 
	else if (smp_volt >= 1300) 
	{
        calc_ver = 4;
    } 
	else if (smp_volt >= 1100) 
	{
        calc_ver = 3;
    } 
	else if (smp_volt >= 900) 
	{
        calc_ver = 2;
    } 
	else if (smp_volt >= 700) 
	{
        calc_ver = 1;
    } 
	else if (smp_volt >= 500) 
	{
        calc_ver = 0;
    } 
	else 
	{
        calc_ver = 0;
    }
	
	var_set_data(VAR_ID_HARD_VER , calc_ver);
}

void sample_clr_sc_prp(void)
{
	cmd_clr_sc = 1;
}

uint8_t sample_set_sc_clr_state(void)
{
	return cmd_clr_sc;
}

void sample_calib_zero(void)
{
    uint16_t set_val = 0;
    
    if(PARAM_ZERO_VAILD(smp_data_obj.src_curr))
    {
        set_val = (smp_data_obj.src_curr + VAR_CURR_OFFSET)/VAR_CURR_FACTOR;
        param_set_data(PAR_ID_CB_ZERO_SET , set_val);
    }
}

void sample_calib_chg(uint16_t set_val)
{
    float calc_k = 0;
    float curr_zero = 0;
    double smp_curr = 0; // 改为double
    curr_zero = param_get_data(PAR_ID_CB_ZERO_SET);
	curr_zero = curr_zero* VAR_CURR_FACTOR - VAR_CURR_OFFSET;
	smp_curr = smp_data_obj.src_curr;
    if(PARAM_ZERO_VAILD(curr_zero))
    {
        smp_curr -= curr_zero;
    }
	
    if(smp_curr > 0)
    {
        calc_k = 10000 * (uint32_t)set_val * 0.1 / smp_curr ;
        if(PARAM_K_IS_VAILD(calc_k))
        {
            param_set_data(PAR_ID_CB_CC_K , calc_k);
        }
    }
}

void sample_calib_dsg(uint16_t set_val)
{
    float calc_k = 0;
    float curr_zero = 0;
    double smp_curr = 0;  // 改为double
    curr_zero = param_get_data(PAR_ID_CB_ZERO_SET);
	curr_zero = curr_zero* VAR_CURR_FACTOR - VAR_CURR_OFFSET;
	smp_curr = smp_data_obj.src_curr;
    if(PARAM_ZERO_VAILD(curr_zero))
    {
        smp_curr -= curr_zero;
    }
    if(smp_curr < 0)
    {
        calc_k = 10000 * (uint32_t)set_val * 0.1 / (-smp_curr);
        if(PARAM_K_IS_VAILD(calc_k))
        {
            param_set_data(PAR_ID_CB_DC_K , calc_k);
        }
    }
}

void sample_calib_cvolt(uint8_t cell_id , uint16_t set_val)
{
    float calc_k = 0;
    
    if((cell_id >= CELL_MAX_NUM) || (smp_data_obj.cv_src_buf[cell_id] == 0))
        return ;
    
    calc_k = 10000 * set_val / smp_data_obj.cv_src_buf[cell_id];
    
    if(PARAM_K_IS_VAILD(calc_k))
    {
        param_set_data(PAR_ID_CB_CV01_K + cell_id, calc_k);
    }
}

void sample_restart_prechg(void)
{
	prechg_flag = 1;
	mcu_delay_ms(100);
	prechg_dly = 0;
}
void sample_fault_clear(uint32_t cycle)
{
	
	if(var_get_data(VAR_ID_FAULT_CLEAR_STATE) == 0)
	{
		if(TRUE == is_happen_dsg_prp())
		{
			fault_clear_cnt += cycle;			
			// 4小时计时
			if(fault_clear_cnt >= FAULT_CLEAR_TIMES)
			{
				var_set_data(VAR_ID_FAULT_CLEAR_STATE , 1);	
				fault_clear_cnt = 0;               		
			} 
	    }
		else
		{
		   fault_clear_cnt = 0;
			
		}
	}
	else
	{
		
	}	
}

//uint8_t sample_calc_temp_num(void)
//{
//	uint8_t cell_num = 0;
//	uint8_t temp_num = 0;
//	uint8_t set_temp_num = 0;	
//	set_temp_num = param_get_data(PAR_ID_CB_TEMP_NUM);	
//	cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
//	
//	if(cell_num <= 8)
//		temp_num = 2;
//	else if(cell_num <= 12)
//		temp_num = 3;
//	else 
//		temp_num = 4;
////	
////    if(temp_num < set_temp_num)			
////		temp_num = set_temp_num;
//	
//	return temp_num;
//}
float sample_get_curr(void)
{
	return bus_curr;
}
/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static int16_t find_ntc_table(uint32_t res , ntc_table_type ntc_data)
{
    uint16_t i = 0;
    int16_t calc_temp = 0;
    if((res > ntc_data.ntc_table[0]) || (res < ntc_data.ntc_table[ntc_data.size - 1]))
    {
        return INVALID_TEMP;
    }

    for(i = 0;i < ntc_data.size - 1; ++ i)
    {
        if((res <= ntc_data.ntc_table[i]) && (res >= ntc_data.ntc_table[i + 1]))
        {
            calc_temp = (i + 1) * 10 - (float)(res - (float)ntc_data.ntc_table[i+1])*10/(ntc_data.ntc_table[i] - ntc_data.ntc_table[i+1]);

            return (calc_temp - 400);
        }
    }

    return INVALID_TEMP;
}

static uint8_t is_happen_chg_prp(void)
{
	if(diag_get_prp(PRP_ID_BOV) || diag_get_prp(PRP_ID_COV) || diag_get_prp(PRP_ID_OCC)
		||diag_get_prp(PRP_ID_OTC) || diag_get_prp(PRP_ID_UTC) || diag_get_prp(PRP_ID_OTE)
		||diag_get_prp(PRP_ID_UTE) || diag_get_prp(PRP_ID_OTM) || diag_get_prp(PRP_ID_COL)
		||diag_get_prp(PRP_ID_TOL) || diag_get_prp(PRP_ID_OCC2)||diag_get_prp(PRP_ID_VDIFF)
		||diag_get_prp(PRP_ID_FT_DMOS)||diag_get_prp(PRP_ID_FT_CMOS))
	return TRUE;
	
	return FALSE;
}

static uint8_t is_happen_dsg_prp(void)
{
	if(diag_get_prp(PRP_ID_BUV) || diag_get_prp(PRP_ID_CUV) || diag_get_prp(PRP_ID_OCD)
		||diag_get_prp(PRP_ID_OTD) || diag_get_prp(PRP_ID_UTD) || diag_get_prp(PRP_ID_OTE)
		||diag_get_prp(PRP_ID_UTE) || diag_get_prp(PRP_ID_OTM) || diag_get_prp(PRP_ID_COL)
		||diag_get_prp(PRP_ID_TOL) || diag_get_prp(PRP_ID_OCD2) || diag_get_prp(PRP_ID_SC)
		||diag_get_prp(PRP_ID_VDIFF)||diag_get_prp(PRP_ID_FT_DMOS)||diag_get_prp(PRP_ID_FT_CMOS))
	return TRUE;
	
	return FALSE;
}

static uint8_t smp_blc_is_open(void)
{
	uint16_t blc_mode = 0;
	
	if(diag_get_prp(PRP_ID_COL) 
		|| diag_get_prp(PRP_ID_OTC) 
		|| diag_get_prp(PRP_ID_OTD)
		|| diag_get_prp(PRP_ID_TOL)
		|| diag_get_prp(PRP_ID_TOL)
		|| diag_get_prp(PRP_ID_UTC)
		|| diag_get_prp(PRP_ID_UTD)
	    || diag_get_prp(PRP_ID_FT_CMOS)
		|| diag_get_prp(PRP_ID_FT_DMOS))
	{
		return FALSE;
	}
	else 
	{
		blc_mode = param_get_data(PAR_ID_BLC_MODE);
		if(PARAM_BLC_MODE_STATIC == blc_mode)
		{
			if(var_get_data(VAR_ID_CURR_DR) != CURR_DR_DSG)
				return TRUE;
			else
				return FALSE;
		}
		else
		{
			if(var_get_data(VAR_ID_CURR_DR) == CURR_DR_CHG)
				return TRUE;
			else
				return FALSE;
		}
	}
}

static uint8_t is_happen_limit_prp(void)
{
	if(diag_get_prp(PRP_ID_BOV) || diag_get_prp(PRP_ID_COV)
		||diag_get_prp(PRP_ID_OTC) || diag_get_prp(PRP_ID_UTC) || diag_get_prp(PRP_ID_OTE)
		||diag_get_prp(PRP_ID_UTE) || diag_get_prp(PRP_ID_OTM) || diag_get_prp(PRP_ID_COL)
		||diag_get_prp(PRP_ID_TOL) ||diag_get_prp(PRP_ID_VDIFF))
		return TRUE;
	
	if((0 == diag_get_prp(PRP_ID_OCC)) && (0 == diag_get_prp(PRP_ID_OCC2)))
		return TRUE;
	
	return FALSE;
}

static uint8_t is_open_limit(void)
{
	if(diag_get_prp(PRP_ID_BOV) || diag_get_prp(PRP_ID_COV)
		||diag_get_prp(PRP_ID_OTC) || diag_get_prp(PRP_ID_UTC) || diag_get_prp(PRP_ID_OTE)
		||diag_get_prp(PRP_ID_UTE) || diag_get_prp(PRP_ID_OTM) || diag_get_prp(PRP_ID_COL)
		||diag_get_prp(PRP_ID_TOL) || diag_get_prp(PRP_ID_VDIFF))
		return FALSE;
	
	/* 发生充电限流 未发生充电限流类保护 */
	if(diag_get_prp(PRP_ID_OCC) || diag_get_prp(PRP_ID_OCC2))
		return TRUE;
	
	return FALSE;
}

/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/


